

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TwoThread {

    private int start = 1;

    //对 flag 的写入虽然加锁保证了线程安全，但读取的时候由于 不是 volatile 所以可能会读取到旧值
    private volatile boolean flag = false;

    //重入锁,ReentrantLock
    private final static Lock lock = new ReentrantLock();

    public static void main(String[] args){
        TwoThread twoThread = new TwoThread();

        Thread t1 = new Thread(new JiNum(twoThread),"even");


        Thread t2 = new Thread(new OuNum(twoThread),"odd");


        t1.start();
        t2.start();
    }

    //奇数线程
    public static class JiNum implements Runnable{

        private TwoThread number;

        public JiNum(TwoThread number){
            this.number = number;
        }

        @Override
        public void run() {
            while(number.start <= 100){
                if(!number.flag){
                    lock.lock();
                    try{

                        System.out.println(Thread.currentThread().getName() + "+-+" + number.start);
                        number.start ++ ;
                        number.flag = true;
                    }finally{
                        lock.unlock();
                    }
                }
            }
        }

    }

    //偶数线程
    public static class OuNum implements Runnable{

        private TwoThread number;

        public OuNum(TwoThread number){
            this.number = number;
        }

        @Override
        public void run() {
            while(number.start <= 100){
                if(number.flag){
                    lock.lock();
                    try{
                        System.out.println(Thread.currentThread().getName() + "+-+" + number.start);
                        number.start ++ ;
                        number.flag = false;
                    }finally{
                        lock.unlock();
                    }
                }
            }
        }
    }
}
